package com.nlscan.qdkit.common.core.util

import android.annotation.SuppressLint
import android.os.Build

/**
 * <pre>
 *     author: breeze
 *     time  : 2023/05/14
 *     desc  : 系统API工具类
 *     封装Android系统非SDK API接口，使用反射方式调用
 * </pre>
 */
class SystemApiUtils private constructor() {

    init {
        throw UnsupportedOperationException("u can't instantiate me...")
    }

    companion object {
        /**
         * 通过反射获取系统属性
         *
         * @param key 属性键名
         * @return 属性值，如果获取失败则返回空字符串
         */
        @SuppressLint("PrivateApi")
        @JvmStatic
        fun getSystemProperty(key: String): String {
            return getSystemProperty(key, "")
        }

        /**
         * 通过反射获取系统属性
         *
         * @param key 属性键名
         * @param defaultValue 默认值
         * @return 属性值，如果获取失败则返回默认值
         */
        @SuppressLint("PrivateApi")
        @JvmStatic
        fun getSystemProperty(key: String, defaultValue: String): String {
            try {
                val clazz = Class.forName("android.os.SystemProperties")
                val getMethod = clazz.getMethod("get", String::class.java, String::class.java)
                return getMethod.invoke(clazz, key, defaultValue) as String
            } catch (e: Exception) {
                return defaultValue
            }
        }

        /**
         * 通过反射设置系统属性
         *
         * @param key 属性键名
         * @param value 属性值
         * @return 是否设置成功
         */
        @SuppressLint("PrivateApi")
        @JvmStatic
        fun setSystemProperty(key: String, value: String): Boolean {
            try {
                val clazz = Class.forName("android.os.SystemProperties")
                val setMethod = clazz.getMethod("set", String::class.java, String::class.java)
                setMethod.invoke(clazz, key, value)
                return true
            } catch (e: Exception) {
                return false
            }
        }

        /**
         * 获取系统属性整数值
         *
         * @param key 属性键名
         * @param defaultValue 默认值
         * @return 属性整数值，如果获取失败则返回默认值
         */
        @SuppressLint("PrivateApi")
        @JvmStatic
        fun getSystemPropertyInt(key: String, defaultValue: Int): Int {
            try {
                val clazz = Class.forName("android.os.SystemProperties")
                val getIntMethod = clazz.getMethod("getInt", String::class.java, Int::class.java)
                return getIntMethod.invoke(clazz, key, defaultValue) as Int
            } catch (e: Exception) {
                return defaultValue
            }
        }

        /**
         * 获取系统属性长整数值
         *
         * @param key 属性键名
         * @param defaultValue 默认值
         * @return 属性长整数值，如果获取失败则返回默认值
         */
        @SuppressLint("PrivateApi")
        @JvmStatic
        fun getSystemPropertyLong(key: String, defaultValue: Long): Long {
            try {
                val clazz = Class.forName("android.os.SystemProperties")
                val getLongMethod = clazz.getMethod("getLong", String::class.java, Long::class.java)
                return getLongMethod.invoke(clazz, key, defaultValue) as Long
            } catch (e: Exception) {
                return defaultValue
            }
        }

        /**
         * 获取系统属性布尔值
         *
         * @param key 属性键名
         * @param defaultValue 默认值
         * @return 属性布尔值，如果获取失败则返回默认值
         */
        @SuppressLint("PrivateApi")
        @JvmStatic
        fun getSystemPropertyBoolean(key: String, defaultValue: Boolean): Boolean {
            try {
                val clazz = Class.forName("android.os.SystemProperties")
                val getBooleanMethod = clazz.getMethod("getBoolean", String::class.java, Boolean::class.java)
                return getBooleanMethod.invoke(clazz, key, defaultValue) as Boolean
            } catch (e: Exception) {
                return defaultValue
            }
        }

        /**
         * 判断是否存在指定的系统属性
         *
         * @param key 属性键名
         * @return 是否存在该属性
         */
        @SuppressLint("PrivateApi")
        @JvmStatic
        fun hasSystemProperty(key: String): Boolean {
            return getSystemProperty(key).isNotEmpty()
        }
    }
}